using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Services.Client;
using System.Linq;
using System.Net;

namespace CloudStorage.API.Entities
{
	/// <summary>
	/// Extracted interface from <see cref="System.Data.Services.Client.DataServiceContext"/> with our added <see cref="GetEntitySet{TEntity}"/>
	/// </summary>
	public interface IEntityTableDataContext
	{
		/// <summary>
		/// Get access to an entity set handled by this <see cref="IEntityTableDataContext"/>
		/// </summary>
		/// <typeparam name="TEntity"></typeparam>
		/// <returns></returns>
		IQueryable<TEntity> GetEntitySet<TEntity>() where TEntity : IEntity;

		/// <summary>
		/// For testing purposes - all objects has this.
		/// </summary>
		Type GetType();

		#region System.Data.Services.Client.DataServiceContext

		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		DataServiceQuery<T> CreateQuery<T>(string entitySetName);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		Uri GetMetadataUri();
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		IAsyncResult BeginLoadProperty(object entity, string propertyName, AsyncCallback callback, object state);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		QueryOperationResponse EndLoadProperty(IAsyncResult asyncResult);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		QueryOperationResponse LoadProperty(object entity, string propertyName);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		IAsyncResult BeginExecuteBatch(AsyncCallback callback, object state, params DataServiceRequest[] queries);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		DataServiceResponse EndExecuteBatch(IAsyncResult asyncResult);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		DataServiceResponse ExecuteBatch(params DataServiceRequest[] queries);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		IAsyncResult BeginExecute<TElement>(Uri requestUri, AsyncCallback callback, object state);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		IEnumerable<TElement> EndExecute<TElement>(IAsyncResult asyncResult);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		IEnumerable<TElement> Execute<TElement>(Uri requestUri);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		IAsyncResult BeginSaveChanges(AsyncCallback callback, object state);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		IAsyncResult BeginSaveChanges(SaveChangesOptions options, AsyncCallback callback, object state);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		DataServiceResponse EndSaveChanges(IAsyncResult asyncResult);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		DataServiceResponse SaveChanges();
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		DataServiceResponse SaveChanges(SaveChangesOptions options);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		void AddLink(object source, string sourceProperty, object target);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		void AttachLink(object source, string sourceProperty, object target);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		bool DetachLink(object source, string sourceProperty, object target);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		void DeleteLink(object source, string sourceProperty, object target);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		void SetLink(object source, string sourceProperty, object target);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		void AddObject(string entitySetName, object entity);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		void AttachTo(string entitySetName, object entity);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		void AttachTo(string entitySetName, object entity, string etag);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		void DeleteObject(object entity);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		bool Detach(object entity);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		void UpdateObject(object entity);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		bool TryGetEntity<TEntity>(Uri identity, out TEntity entity) where TEntity : class;
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		bool TryGetUri(object entity, out Uri identity);
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		Uri BaseUri { get; }
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		ICredentials Credentials { get; set; }
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		MergeOption MergeOption { get; set; }
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		bool IgnoreMissingProperties { get; set; }
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		string DataNamespace { get; set; }
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		Func<Type, string> ResolveName { get; set; }
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		Func<string, Type> ResolveType { get; set; }
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		int Timeout { get; set; }
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		Uri TypeScheme { get; set; }
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		bool UsePostTunneling { get; set; }
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		ReadOnlyCollection<LinkDescriptor> Links { get; }
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		ReadOnlyCollection<EntityDescriptor> Entities { get; }
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		SaveChangesOptions SaveChangesDefaultOptions { get; set; }
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		event EventHandler<SendingRequestEventArgs> SendingRequest;
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		event EventHandler<ReadingWritingEntityEventArgs> ReadingEntity;
		/// <summary>
		/// <see cref="System.Data.Services.Client.DataServiceContext"/>
		/// </summary>
		event EventHandler<ReadingWritingEntityEventArgs> WritingEntity;

		#endregion
	}
}